package com.ray.business.api;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ray.base.service.BaseCustomerService;
import com.ray.base.table.entity.BaseCustomer;
import com.ray.business.builder.DeductionBuilder;
import com.ray.business.builder.PurchaseDeductionBuilder;
import com.ray.business.check.BusinessCheck;
import com.ray.business.check.DeductionCheck;
import com.ray.business.check.PurchaseCheck;
import com.ray.business.check.PurchaseDeductionCheck;
import com.ray.business.enums.DeductionStatusEnum;
import com.ray.business.service.ProdPurchaseDeductionService;
import com.ray.business.service.ProdBusinessService;
import com.ray.business.service.ProdPurchaseService;
import com.ray.business.table.dto.DeductionQueryDTO;
import com.ray.business.table.entity.ProdBusiness;
import com.ray.business.table.entity.ProdPurchase;
import com.ray.business.table.entity.ProdPurchaseDeduction;
import com.ray.business.table.params.deduction.DeductionCreateParams;
import com.ray.business.table.params.deduction.DeductionEditParams;
import com.ray.business.table.params.deduction.DeductionQueryParams;
import com.ray.business.table.vo.DeductionVO;
import com.ray.common.SysMsgCodeConstant;
import com.ray.system.builder.CommonPageBuilder;
import com.ray.validate.support.utils.ValidateUtil;
import com.ray.woodencreate.beans.LoginUser;
import com.ray.woodencreate.enums.YesOrNoEnum;
import com.ray.woodencreate.exception.BusinessExceptionFactory;
import com.ray.woodencreate.page.CommonPage;
import com.ray.woodencreate.result.MsgCodeConstant;
import com.ray.woodencreate.result.Result;
import com.ray.woodencreate.result.ResultFactory;
import com.ray.woodencreate.util.Assert;
import com.ray.woodencreate.util.LogInUserUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author bo shen
 * @Description: 扣款单相关服务
 * @Class: PurchaseDeductionApi
 * @Package com.ray.base.api
 * @date 2020/5/27 11:15
 * @company <p>Ray快速开发平台</p>
 * @updateRecord time(修改时间)  author(修改人)   desc(修改内容)
 */
@Service
@Slf4j
public class PurchaseDeductionApi {

    @Autowired
    private ProdPurchaseDeductionService prodPurchaseDeductionService;
    @Autowired
    private BaseCustomerService baseCustomerService;
    @Autowired
    private ProdPurchaseService prodPurchaseService;

    /**
     * 查询扣款单列表信息 分页  非删除的
     *
     * @param queryParams
     * @return
     */
    public Result<IPage<DeductionVO>> pagePurchaseDeductions(CommonPage<DeductionQueryParams, Page<DeductionVO>> queryParams) {
        Assert.notNull(queryParams, SysMsgCodeConstant.Error.ERR10000001);
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        CommonPageBuilder<DeductionQueryDTO, ProdPurchaseDeduction> commonPageBuilder = new CommonPageBuilder<>(DeductionQueryDTO.class);
        commonPageBuilder.appendEntity(queryParams.getEntity()).appendQuery(queryParams.getQuery()).appendPage(queryParams.getPage());
        IPage<ProdPurchaseDeduction> page = prodPurchaseDeductionService.page(commonPageBuilder.bulid(), loginUser);
        List<ProdPurchaseDeduction> orders = page.getRecords();
        //结果对象
        IPage<DeductionVO> pageList = new Page<>();
        pageList.setTotal(page.getTotal());
        pageList.setCurrent(page.getCurrent());
        pageList.setSize(page.getSize());
        Map<String, BaseCustomer> baseCustomerMap = new HashMap<>();

        //查询到结果 数据转换
        if (ObjectUtil.isNotNull(orders)) {
            pageList.setRecords(orders.stream().map(sysPurchaseDeduction -> {
                DeductionVO orderVO = new DeductionVO();
                BeanUtil.copyProperties(sysPurchaseDeduction, orderVO);
                //查询客信息
                BaseCustomer baseCustomer = baseCustomerMap.get(sysPurchaseDeduction.getCustomerCode());
                if (ObjectUtil.isEmpty(baseCustomer)) {
                    baseCustomer = baseCustomerService.queryCustomerByCustomerCode(sysPurchaseDeduction.getCustomerCode(), loginUser);
                    baseCustomerMap.put(sysPurchaseDeduction.getCustomerCode(), baseCustomer);
                }
                orderVO.setCustomerName(baseCustomer.getCustomerName());
                return orderVO;
            }).collect(Collectors.toList()));
        } else {
            pageList.setRecords(new ArrayList<>());
        }
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000002, pageList);
    }

    /**
     * 查询扣款单列表信息--启用的扣款单
     *
     * @param queryParams
     * @return
     */
    public Result<List<DeductionVO>> queryPurchaseDeductions(DeductionQueryParams queryParams) {
        Assert.notNull(queryParams, "参数[]不存在");
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        DeductionQueryDTO queryDTO = new DeductionQueryDTO();
        BeanUtil.copyProperties(queryParams, queryDTO);
        queryDTO.setStatus(YesOrNoEnum.YES.getValue());
        List<ProdPurchaseDeduction> orders = prodPurchaseDeductionService.list(queryDTO, loginUser);
        //查询对象
        List<DeductionVO> list = new ArrayList<>();
        if (ObjectUtil.isNotNull(orders)) {
            list = orders.stream().map(sysPurchaseDeduction -> {
                DeductionVO orderVO = new DeductionVO();
                BeanUtil.copyProperties(sysPurchaseDeduction, orderVO);
                return orderVO;
            }).collect(Collectors.toList());
        }
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000002, list);
    }


    /**
     * 创建扣款单
     *
     * @param createParams 创建对象
     * @return Result
     */
    @Transactional
    public Result<String> createPurchaseDeduction(DeductionCreateParams createParams) {
        ValidateUtil.validate(createParams);
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        //查询客户数据
        ProdPurchase prodPurchase = prodPurchaseService.queryPurchaseByPurchaseCode(createParams.getBusinessCode(), loginUser);
        new PurchaseCheck(prodPurchase).checkNull("采购单不存在").canDeduction("采购单不能扣款");
        PurchaseDeductionBuilder orderBuilder = new PurchaseDeductionBuilder();
        orderBuilder.append(createParams).append(prodPurchase).appendStatus(DeductionStatusEnum.UN_CHECK.getValue())
                .appendStatus(YesOrNoEnum.YES.getValue()).appendCreate(loginUser);
        //保存扣款单信息
        if (!prodPurchaseDeductionService.save(orderBuilder.bulid())) {
            log.info("保存扣款单接口异常,参数:{}", JSON.toJSONString(orderBuilder.bulid()));
            throw BusinessExceptionFactory.newException("保存扣款单异常");
        }
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000001, orderBuilder.getCode());
    }

    /**
     * 编辑扣款单
     *
     * @param editParams 编辑对象
     * @return Result
     */
    @Transactional
    public Result<String> editPurchaseDeduction(DeductionEditParams editParams) {
        ValidateUtil.validate(editParams);
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        ProdPurchaseDeduction prodPurchaseDeduction = prodPurchaseDeductionService.queryPurchaseDeductionByPurchaseDeductionCode(editParams.getDeductionCode(), loginUser);
        new PurchaseDeductionCheck(prodPurchaseDeduction).checkNull("扣款单不存在").checkEdit("扣款单不能编辑");
        PurchaseDeductionBuilder orderBuilder = new PurchaseDeductionBuilder();
        orderBuilder.append(editParams).appendEdit(loginUser);
        //编辑扣款单信息
        if (!prodPurchaseDeductionService.edit(orderBuilder.bulid(), loginUser)) {
            log.info("编辑扣款单接口异常,参数:{}", JSON.toJSONString(orderBuilder.bulid()));
            throw BusinessExceptionFactory.newException("编辑扣款单失败");
        }
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000001, orderBuilder.getCode());
    }


    /**
     * 删除扣款单
     *
     * @param deductionCode 扣款单编码
     * @return Result
     */
    @Transactional
    public Result<String> deletePurchaseDeduction(String deductionCode) {
        ValidateUtil.hasLength(deductionCode, "参数[deductionCode]不能为空");
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        //获取权限信息
        ProdPurchaseDeduction prodPurchaseDeduction = prodPurchaseDeductionService.queryPurchaseDeductionByPurchaseDeductionCode(deductionCode, loginUser);
        new PurchaseDeductionCheck(prodPurchaseDeduction).checkNull("扣款单不存在");
        //查询客户数据
        ProdPurchase prodPurchase = prodPurchaseService.queryPurchaseByPurchaseCode(prodPurchaseDeduction.getBusinessCode(), loginUser);
        new PurchaseCheck(prodPurchase).checkNull("采购单不存在").canDeleteDeduction("采购单已经对账");
        PurchaseDeductionBuilder orderBuilder = new PurchaseDeductionBuilder();
        orderBuilder.appendCode(deductionCode).appendEdit(loginUser).delete();
        //删除扣款单信息
        if (!prodPurchaseDeductionService.edit(orderBuilder.bulid(), loginUser)) {
            log.info("删除扣款单接口异常,参数:{}", JSON.toJSONString(orderBuilder.bulid()));
            throw BusinessExceptionFactory.newException("删除失败");
        }
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000001, orderBuilder.getCode());
    }


    /**
     * 审核扣款单
     *
     * @param deductionCode 扣款单编码
     * @return Result
     */
    @Transactional
    public Result<String> passPurchaseDeduction(String deductionCode) {
        ValidateUtil.hasLength(deductionCode, "参数[deductionCode]不能为空");
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        //获取权限信息
        //获取权限信息
        ProdPurchaseDeduction prodPurchaseDeduction = prodPurchaseDeductionService.queryPurchaseDeductionByPurchaseDeductionCode(deductionCode, loginUser);
        new PurchaseDeductionCheck(prodPurchaseDeduction).checkNull("扣款单不存在").checkCanCheck("扣款单已审核");
        PurchaseDeductionBuilder orderBuilder = new PurchaseDeductionBuilder();
        orderBuilder.appendCode(deductionCode).appendEdit(loginUser).appendStatus(DeductionStatusEnum.PASS.getValue());
        //开启扣款单信息
        if (!prodPurchaseDeductionService.edit(orderBuilder.bulid(), loginUser)) {
            log.info("开启扣款单接口异常,参数:{}", JSON.toJSONString(orderBuilder.bulid()));
            throw BusinessExceptionFactory.newException("审核失败");
        }
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000001, orderBuilder.getCode());
    }


    /**
     * 扣款单详情
     *
     * @param deductionCode 扣款单编码
     * @return Result
     */
    public Result<DeductionVO> viewPurchaseDeduction(String deductionCode) {
        ValidateUtil.hasLength(deductionCode, "参数[deductionCode]不能为空");
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        //获取权限信息
        ProdPurchaseDeduction sysPurchaseDeduction = prodPurchaseDeductionService.queryPurchaseDeductionByPurchaseDeductionCode(deductionCode, loginUser);
        new PurchaseDeductionCheck(sysPurchaseDeduction).checkNull("扣款单不存在");
        DeductionVO orderVO = new DeductionVO();
        BeanUtil.copyProperties(sysPurchaseDeduction, orderVO);
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000002, orderVO);
    }

}
